﻿Public Class JoinDesignerTable

    Protected WithEvents _Represents As Core.Functions.MetisRefFunction
    Protected WithEvents _FieldList As Core.Functions.MetisFunctionFieldList

    Sub New(ByVal Represents As Core.Functions.MetisRefFunction)
        InitializeComponent()

        _Represents = Represents
        _FieldList = _Represents.ReferencedFunction.Fields

        Text = If(_Represents.Alias.Equals(_Represents.ReferencedFunction.Name, StringComparison.OrdinalIgnoreCase), _Represents.Alias, String.Format("{0} ({1})", _Represents.Alias, _Represents.ReferencedFunction.Name))
        For Each field As Metis.Core.Functions.MetisFunctionField In _FieldList
            Dim item As ListViewItem = lstFields.Items.Add(field.ID.ToString, field.Name, "STRING")
            item.Tag = field
            If field.DBfieldType = Core.DB.DBFieldType.DBdate Then
                item.ImageKey = "DATE"
            ElseIf field.DBfieldType = Core.DB.DBFieldType.DBnumber Then
                item.ImageKey = "NUMBER"
            End If
        Next
        lstFields.Columns(0).Width = -2
    End Sub

    Public ReadOnly Property Represents() As Core.Functions.MetisRefFunction
        Get
            Return _Represents
        End Get
    End Property

    Sub HandleNameChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) Handles _Represents.PropertyChanged
        If Not String.IsNullOrEmpty(e.PropertyName) AndAlso e.PropertyName = "Alias" Then
            Text = If(_Represents.Alias.Equals(_Represents.ReferencedFunction.Name, StringComparison.OrdinalIgnoreCase), _Represents.Alias, String.Format("{0} ({1})", _Represents.Alias, _Represents.ReferencedFunction.Name))
        End If
    End Sub

    Public Function FieldLocation(ByVal field As Core.Functions.MetisFunctionField) As System.Drawing.Point
        Dim MaxY As Integer = Me.Location.Y + (Me.PointToScreen(lstFields.Location).Y - Me.Parent.PointToScreen(Me.Location).Y) + lstFields.Location.Y + lstFields.Size.Height

        For Each item As ListViewItem In lstFields.Items
            If field.Equals(item.Tag) Then
                Dim tmpLoc As System.Drawing.Point = item.Position
                tmpLoc.Y += Me.Location.Y + (Me.PointToScreen(lstFields.Location).Y - Me.Parent.PointToScreen(Me.Location).Y) + lstFields.Location.Y
                tmpLoc.Y = Math.Min(tmpLoc.Y, MaxY)

                Return tmpLoc
            End If
        Next
    End Function

    Private Sub lstFields_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles lstFields.MouseDown
        Dim Item As ListViewItem = lstFields.GetItemAt(e.X, e.Y)
        If Item IsNot Nothing Then
            Item.Selected = True
            Dim DragDropStructure As New JoinDragDropStruct(_Represents, Item.Tag)
            lstFields.DoDragDrop(DragDropStructure, DragDropEffects.Move)
        End If

    End Sub

    Protected Overrides Sub WndProc(ByRef WndMsg As System.Windows.Forms.Message)
        Const WM_NCRBUTTONDOWN = &HA4
        If WndMsg.Msg = WM_NCRBUTTONDOWN AndAlso Me.ContextMenuStrip IsNot Nothing Then
            DirectCast(Me.Parent, JoinDesigner)._SelectedTable = _Represents
            Me.ContextMenuStrip.Show(Control.MousePosition)
        End If
        MyBase.WndProc(WndMsg)
    End Sub

    Private Sub lstFields_Resize(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lstFields.Resize
        lstFields.Columns(0).Width = -2
    End Sub

    Private Sub lstFields_DragOver(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles lstFields.DragOver, lstFields.DragEnter
        If e.Data.GetDataPresent(GetType(JoinDragDropStruct)) AndAlso _
           Not DirectCast(e.Data.GetData(GetType(JoinDragDropStruct)), JoinDragDropStruct).FuncRef.Equals(Me.Represents) Then
            Dim tmpPoint As System.Drawing.Point = lstFields.PointToClient(New System.Drawing.Point(e.X, e.Y))
            Dim TargetItem As ListViewItem = lstFields.GetItemAt(tmpPoint.X, tmpPoint.Y)
            If TargetItem IsNot Nothing AndAlso _
                DirectCast(e.Data.GetData(GetType(JoinDragDropStruct)), JoinDragDropStruct).FuncField.DBfieldType = _
                DirectCast(TargetItem.Tag, Core.Functions.MetisFunctionField).DBfieldType Then
                e.Effect = DragDropEffects.Move
            Else
                e.Effect = DragDropEffects.None
            End If
        End If
    End Sub


    Private Sub lstFields_DragDrop(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles lstFields.DragDrop
        If e.Data.GetDataPresent(GetType(JoinDragDropStruct)) AndAlso _
           Not DirectCast(e.Data.GetData(GetType(JoinDragDropStruct)), JoinDragDropStruct).FuncRef.Equals(Me.Represents) Then
            Dim tmpPoint As System.Drawing.Point = lstFields.PointToClient(New System.Drawing.Point(e.X, e.Y))
            Dim Item As ListViewItem = lstFields.GetItemAt(tmpPoint.X, tmpPoint.Y)
            Item.Selected = True

            Dim tmpLeftFuncRef As Core.Functions.MetisRefFunction = DirectCast(e.Data.GetData(GetType(JoinDragDropStruct)), JoinDragDropStruct).FuncRef
            Dim tmpLeftField As Core.Functions.MetisFunctionField = DirectCast(e.Data.GetData(GetType(JoinDragDropStruct)), JoinDragDropStruct).FuncField
            Dim tmpRightFuncRef As Core.Functions.MetisRefFunction = _Represents
            Dim tmpRightField As Core.Functions.MetisFunctionField = DirectCast(Item.Tag, Core.Functions.MetisFunctionField)

            _Represents.OwningFunction.Joins.Add(New Core.Functions.MetisJoin(tmpLeftFuncRef, tmpLeftField, tmpRightFuncRef, tmpRightField, _Represents.OwningFunction))
        End If


    End Sub
End Class
